#  Copyright (c) 2012 Matthew Mitchell
#
#  This file is part of cbitcoin. It is subject to the license terms
#  in the LICENSE file found in the top-level directory of this
#  distribution and at http://www.cbitcoin.com/license.html. No part of
#  cbitcoin, including this file, may be copied, modified, propagated,
#  or distributed except according to the terms contained in the
#  LICENSE file.

# REMEMBER to add dependencies after the objects or libraries that depend on them.

# Setup

INCDIR = $(CURDIR)/include
BINDIR = $(CURDIR)/bin
INCCLIENT = -I/$(CURDIR)/client-server/include
LFLAGS += -L/opt/local/lib -L/usr/local/ssl/lib @CONFIGLFLAGS@
CFLAGS += -I$(INCDIR) -I$(CURDIR)/dependencies/threads @CONFIGFLAGS@
CC = @CC@

ifndef OSTYPE
  OSTYPE = $(shell uname -s|awk '{print tolower($$0)}')
  #export OSTYPE
endif

LIBRARY_VERSION = 2.0

ifeq ($(OSTYPE), darwin)
	LFLAGS += -flat_namespace -dynamiclib -undefined dynamic_lookup
	LIBRARY_EXTENSION=.$(LIBRARY_VERSION).dylib
	CFLAGS += -DCB_MACOSX
else # Assuming Linux for now
	LFLAGS += -shared
	LIBRARY_EXTENSION=.$(LIBRARY_VERSION).so
	ADDITIONAL_OPENSSL_FLAGS = -ldl -L/lib/x86_64-linux-gnu/
	export LD_LIBRARY_PATH = $(BINDIR):/usr/local/lib
	CFLAGS += -DCB_LINUX
endif

# Set vpath search paths

vpath %.h include
vpath %.c src
vpath %.o build
vpath %.d build

# Main targets

all: all-build
test: test-build
examples: example-build

# Build all

all-build: library 
library: core crypto random threads logging network 

# Get files for the core library

CORE_FILES = $(wildcard src/*.c)
CORE_OBJS = $(patsubst src/%.c, build/%.o, $(CORE_FILES))

# Core library target linking

core : $(CORE_OBJS) | bin
	$(CC) $(LFLAGS) $(if $(subst darwin,,$(OSTYPE)),,-install_name @executable_path/libcbitcoin$(LIBRARY_EXTENSION)) -o bin/libcbitcoin$(LIBRARY_EXTENSION) $(CORE_OBJS)

# Include header prerequisites

-include build/*.d

# Create build directory

build:
	mkdir build

# Create bin directory

bin:
	mkdir bin

# Core Compilation

$(CORE_OBJS): build/%.o: src/%.c | build
	$(CC) -c $(CFLAGS) $< -o $@
	$(CC) -I$(INCDIR) -MM $< > build/$*.d
	@cp build/$*.d build/$*.P
	@sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
            -e '/^$$/ d' -e 's/$$/ :/' < build/$*.P >> build/$*.d;
	@rm build/$*.P

# Dependencies require include/CBDependencies.h as a prerequisite

build/CBOpenSSLCrypto.o build/CBRand.o CBBlockChainStorage.o CBLibEventSockets.o: include/CBDependencies.h

# Crypto library target linking

crypto : build/CBOpenSSLCrypto.o | bin
	$(CC) $(LFLAGS) $(if $(subst darwin,,$(OSTYPE)),,-install_name @executable_path/libcbitcoin-crypto$(LIBRARY_EXTENSION)) $(ADDITIONAL_OPENSSL_FLAGS) -o bin/libcbitcoin-crypto$(LIBRARY_EXTENSION) build/CBOpenSSLCrypto.o -lcrypto -lssl

# Crypto library compile

build/CBOpenSSLCrypto.o: dependencies/crypto/CBOpenSSLCrypto.c
	$(CC) -c $(CFLAGS) $< -o $@

# Random library target linking

random : build/CBRand.o | bin
	$(CC) $(LFLAGS) $(if $(subst darwin,,$(OSTYPE)),,-install_name @executable_path/libcbitcoin-rand$(LIBRARY_EXTENSION)) -o bin/libcbitcoin-rand$(LIBRARY_EXTENSION) build/CBRand.o

# Random library compile

build/CBRand.o: dependencies/random/CBRand.c
	$(CC) -c $(CFLAGS) $< -o $@

# Network library target linking

network : build/CBLibEventSockets.o build/CBCallbackQueue.o | bin
	$(CC) $(LFLAGS) $(if $(subst darwin,,$(OSTYPE)),,-install_name @executable_path/libcbitcoin-network$(LIBRARY_EXTENSION)) -o bin/libcbitcoin-network$(LIBRARY_EXTENSION) build/CBLibEventSockets.o build/CBCallbackQueue.o -levent_core

# Network library compile

build/CBCallbackQueue.o: dependencies/sockets/CBCallbackQueue.c dependencies/sockets/CBCallbackQueue.h
	$(CC) -c $(CFLAGS) $< -o $@

build/CBLibEventSockets.o: dependencies/sockets/CBLibEventSockets.c dependencies/sockets/CBLibEventSockets.h
	$(CC) -c $(CFLAGS) $< -o $@
	
# Threads library target linking

threads : build/CBThreads.o | bin
	$(CC) $(LFLAGS) $(if $(subst darwin,,$(OSTYPE)),,-install_name @executable_path/libcbitcoin-threads$(LIBRARY_EXTENSION)) -o bin/libcbitcoin-threads$(LIBRARY_EXTENSION) build/CBThreads.o

# Threads library compile

build/CBThreads.o: dependencies/threads/CBThreads.c dependencies/threads/CBThreads.h
	$(CC) -c $(CFLAGS) $< -o $@

# Logging library target linking

logging : build/CBLog.o | bin
	$(CC) $(LFLAGS) $(if $(subst darwin,,$(OSTYPE)),,-install_name @executable_path/libcbitcoin-logging$(LIBRARY_EXTENSION)) -o bin/libcbitcoin-logging$(LIBRARY_EXTENSION) build/CBLog.o

# Logging library compile

build/CBLog.o: dependencies/logging/CBLog.c dependencies/logging/CBLog.h 
	$(CC) -c $(CFLAGS) $< -o $@

# Clean

clean:
	rm -f -r build bin

# Library linking flags

LINK_CORE = -lcbitcoin.$(LIBRARY_VERSION)
LINK_NETWORK = -lcbitcoin-network.$(LIBRARY_VERSION)
LINK_THREADS = -lcbitcoin-threads.$(LIBRARY_VERSION) -lpthread
LINK_LOGGING = -lcbitcoin-logging.$(LIBRARY_VERSION)
LINK_CRYPTO = -lcbitcoin-crypto.$(LIBRARY_VERSION) -lcrypto
LINK_RAND = -lcbitcoin-rand.$(LIBRARY_VERSION)

# Tests

TEST_FILES = $(wildcard test/*.c)
TEST_BINARIES = $(patsubst test/%.c, bin/%, $(TEST_FILES))
TEST_OBJS = $(patsubst test/%.c, build/%.o, $(TEST_FILES))

test-build : clean-tests $(TEST_BINARIES)
	rm -f -r cbitcoin 0 1 2 test.dat testDb test.log
	$(info ALL TESTS SUCCESSFUL)

# REMEMBER to add dependencies after the objects or libraries that depend on them.

$(TEST_BINARIES): bin/%: build/%.o
	$(CC) $< -L$(BINDIR) -Wl,-rpath=\$$ORIGIN $(LINK_CORE) $(LINK_NETWORK) $(LINK_THREADS) $(LINK_LOGGING) $(LINK_CRYPTO) $(LINK_CORE) $(LINK_RAND) -L/opt/local/lib -levent_core -levent_pthreads -o $@
	$@

$(TEST_OBJS): build/%.o: test/%.c library
	$(CC) -c $(CFLAGS) -I$(CURDIR)/dependencies/sockets/ $< -o $@
	
clean-tests:
	rm -f $(TEST_BINARIES)
	
# Examples

EXAMPLE_FILES = $(wildcard examples/*.c)
EXAMPLE_BINARIES = $(patsubst examples/%.c, bin/%, $(EXAMPLE_FILES))
EXAMPLE_OBJS = $(patsubst examples/%.c, build/%.o, $(EXAMPLE_FILES))

example-build : $(EXAMPLE_BINARIES)

# For examples using the crypto dependencies only.

EXAMPLE_CRYPTO_LINK = $(CC) $< -L$(BINDIR) -Wl,-rpath=\$$ORIGIN $(LINK_CORE) $(LINK_CRYPTO) -L/opt/local/lib -o $@

bin/base58ChecksumEncode bin/base58Converter bin/WIFConverter bin/WIF2DER: bin/%: build/%.o
	$(EXAMPLE_CRYPTO_LINK)

# For examples using the crypto and random dependencies

EXAMPLE_CRYPTO_RAND_LINK = $(CC) $< -L$(BINDIR) -Wl,-rpath=\$$ORIGIN $(LINK_CORE) $(LINK_CRYPTO) $(LINK_RAND) -L/opt/local/lib -o $@

bin/addressGenerator:  bin/%: build/%.o
	$(EXAMPLE_CRYPTO_RAND_LINK)

# For examples using the crypto, random and threading dependencies

EXAMPLE_CRYPTO_RAND_THREAD_LINK = $(CC) $< -L$(BINDIR) -Wl,-rpath=\$$ORIGIN $(LINK_CORE) $(LINK_CRYPTO) $(LINK_RAND) $(LINK_THREADS) -L/opt/local/lib -o $@

bin/noLowerAddressGenerator: bin/%: build/%.o
	$(EXAMPLE_CRYPTO_RAND_THREAD_LINK)

# Compilation of example sources

$(EXAMPLE_OBJS): build/%.o: examples/%.c library
	$(CC) -c $(CFLAGS) -I$(CURDIR)/dependencies/sockets/ $< -o $@
	
